<template>
	<div class="dashboard-container" @contextmenu.prevent="showContextMenu($event, null)">
		<div class="icon-grid" ref="iconGrid">
			<div v-for="(item, index) in items" :key="item.id" class="icon-card"
				:class="{ 'is-dragging': draggedIndex === index }" :style="getItemStyle(index)"
				@mousedown="startDrag($event, index)" @dblclick="openIcon(item)"
				@contextmenu.prevent="showContextMenu($event, item)">
				<img :src="item.icon" :alt="item.name" class="icon-image" />
				<span class="icon-name">{{ item.name }}</span>
			</div>
		</div>
		<div v-if="showMenu" :style="menuStyle" class="context-menu">
			<div v-for="option in menuOptions" :key="option.text" @click="handleMenuAction(option)" class="menu-item">
				{{ option.text }}
			</div>
		</div>
	</div>
</template>

<script setup>
import {
	ref,
	onMounted,
	onUnmounted,
	getCurrentInstance,
	computed,
	nextTick
} from 'vue'
import desktopItemsData from './desktopItems.json'

const {
	proxy
} = getCurrentInstance()
const $emit = defineEmits(['qiehuan', 'openWindow'])

const items = ref(desktopItemsData.map(item => ({
	...item,
	icon: proxy.$util.urlProceIcon(item.icon)
})))

const showMenu = ref(false)
const menuStyle = ref({})
const menuOptions = ref([])
const lajichuantou = ref(0)
const iconGrid = ref(null)
const draggedIndex = ref(null)
const dragOffset = ref({
	x: 0,
	y: 0
})
const mousePosition = ref({
	x: 0,
	y: 0
})
// 计算网格大小
const gridSize = computed(() => {
	// 如果iconGrid还未挂载，返回默认值
	if (!iconGrid.value) return {
		columns: 1,
		rows: 1
	}
	// 获取iconGrid的边界矩形
	const rect = iconGrid.value.getBoundingClientRect()
	// 计算列数
	const columns = Math.floor(rect.width / 100)
	// 计算行数
	const rows = Math.ceil(items.value.length / columns)
	return {
		columns,
		rows
	}
})

// 计算每个项目的样式
const getItemStyle = (index) => {
	const {
		columns
	} = gridSize.value
	// 计算项目所在的行和列
	const row = Math.floor(index / columns)
	const col = index % columns
	// 计算项目的x和y坐标
	let x = col * 100
	let y = row * 100
	// 如果正在被拖动
	if (draggedIndex.value === index) {
		// 使用鼠标位置减去拖动偏移来计算新的位置
		x = mousePosition.value.x - dragOffset.value.x
		y = mousePosition.value.y - dragOffset.value.y
	}

	return {
		transform: `translate(${x}px, ${y}px)`,
		transition: draggedIndex.value === index ? 'none' : 'all 0.3s ease',
		zIndex: draggedIndex.value === index ? 10 : 1,
	}
}

// 开始
const startDrag = (event, index) => {
	// 如果不是鼠标左键点击，不拖动
	if (event.button !== 0) return
	// 设置拖动索引
	draggedIndex.value = index
	// 获取被点击元素的信息
	const rect = event.target.getBoundingClientRect()
	// 计算拖动偏移多少
	dragOffset.value = {
		x: event.clientX - rect.left,
		y: event.clientY - rect.top
	}
	// 计算鼠标在网格内的位置
	mousePosition.value = {
		x: event.clientX - iconGrid.value.getBoundingClientRect().left,
		y: event.clientY - iconGrid.value.getBoundingClientRect().top
	}
	document.addEventListener('mousemove', onDrag)
	document.addEventListener('mouseup', stopDrag)
}

// 拖动中
const onDrag = (event) => {
	// 如果没有拖动
	if (draggedIndex.value === null) return
	// 更新鼠标在网格的位置
	mousePosition.value = {
		x: event.clientX - iconGrid.value.getBoundingClientRect().left,
		y: event.clientY - iconGrid.value.getBoundingClientRect().top
	}
	const {
		columns
	} = gridSize.value
	// 计算新的index位置
	const newIndex = Math.floor(mousePosition.value.y / 100) * columns + Math.floor(mousePosition.value.x / 100)
	// 如果新index有效且不同于当前index
	if (newIndex !== draggedIndex.value && newIndex >= 0 && newIndex < items.value.length) {
		const newItems = [...items.value]
		// 移除被拖动的
		const [removed] = newItems.splice(draggedIndex.value, 1)
		// 在新位置放入被拖动的
		newItems.splice(newIndex, 0, removed)
		items.value = newItems
		// 更新index
		draggedIndex.value = newIndex
	}
}

// 停止
const stopDrag = () => {
	// 重置
	draggedIndex.value = null
	document.removeEventListener('mousemove', onDrag)
	document.removeEventListener('mouseup', stopDrag)
}

const showContextMenu = (event, item) => {
	event.preventDefault()
	const {
		clientX,
		clientY
	} = event
	if (item) {
		menuOptions.value = [{
			text: '打开',
			action: () => openIcon(item)
		}]
		lajichuantou.value++
	}
	if (!item && lajichuantou.value == 0) {
		menuOptions.value = [{
			text: '刷新',
			action: refreshDesktop
		},
		{
			text: '切换主题',
			action: toggleTheme
		},
		]
	}
	setTimeout(() => {
		lajichuantou.value = 0
	}, 10)

	const menuWidth = 150
	const menuHeight = menuOptions.value.length * 40
	const screenWidth = window.innerWidth
	const screenHeight = window.innerHeight
	let left = clientX
	let top = clientY
	if (left + menuWidth > screenWidth) {
		left = screenWidth - menuWidth
	}
	if (top + menuHeight > screenHeight) {
		top = screenHeight - menuHeight
	}
	menuStyle.value = {
		top: `${top}px`,
		left: `${left}px`,
	}
	showMenu.value = true
}

const openIcon = (item) => {
	$emit('openWindow', {
		...item,
		iconPath: item.icon // 添加 icon 路径到传递的参数中
	})
}

const refreshDesktop = () => {
	console.log('正在刷新桌面...');
	// 重新加载图标数据
	items.value = desktopItemsData.map(item => ({
		...item,
		icon: proxy.$util.urlProceIcon(item.icon)
	}));

	// 重置拖拽状态
	draggedIndex.value = null;

	// 触发重新渲染
	nextTick(() => {
		console.log('桌面刷新完成');
	});
}


const toggleTheme = () => {
	console.log('换主题')
	$emit('qiehuan')
}

const handleMenuAction = (option) => {
	option.action()
	showMenu.value = false
}

const closeContextMenu = (event) => {
	if (!event.target.closest('.context-menu')) {
		showMenu.value = false
	}
}

onMounted(() => {
	document.addEventListener('click', closeContextMenu)
})

onUnmounted(() => {
	document.removeEventListener('click', closeContextMenu)
	document.removeEventListener('mousemove', onDrag)
	document.removeEventListener('mouseup', stopDrag)
})
</script>

<style scoped>
.dashboard-container {
	min-height: 90vh;
	background: linear-gradient(to bottom right, rgb(243, 244, 246));
	padding: 42px 3px;
	position: relative;
}

.icon-grid {
	position: relative;
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(86px, 1fr));
	gap: 14px;
}

.icon-card {
	position: absolute;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	width: 86px;
	height: 86px;
	padding: 7px;
	border-radius: 10px;
	transition: all 0.3s ease;
	cursor: move;
	user-select: none;
	pointer-events: auto;
}

.icon-card:hover {
	background-color: rgba(255, 255, 255, 0.5);
	box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
}

.icon-card.is-dragging {
	opacity: 0.8;
	transform: scale(1.05);
	box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1);
}

.icon-image {
	width: 60px;
	height: 60px;
	margin-bottom: 7px;
	pointer-events: none;
	border-radius: 50%;
}

.icon-name {
	font-size: 12.25px;
	font-weight: 500;
	color: rgb(255, 255, 255);
	text-align: center;
}

.context-menu {
	position: fixed;
	background-color: rgba(255, 255, 255, 0.8);
	backdrop-filter: blur(10px);
	border-radius: 8px;
	padding: 8px 0;
	min-width: 150px;
	box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
	z-index: 1000;
	animation: fadeIn 0.2s ease-out;
}

.menu-item {
	padding: 8px 16px;
	cursor: pointer;
	transition: background-color 0.2s;
	color: black;
}

.menu-item:hover {
	background-color: rgba(0, 0, 0, 0.05);
}

@keyframes fadeIn {
	from {
		opacity: 0;
		transform: scale(0.95);
	}

	to {
		opacity: 1;
		transform: scale(1);
	}
}
</style>